package cn.qj.ymcc.service.impl;

import cn.qj.ymcc.constants.BusinessConstants;
import cn.qj.ymcc.domain.CourseType;
import cn.qj.ymcc.exception.GlobleBusinessException;
import cn.qj.ymcc.mapper.CourseTypeMapper;
import cn.qj.ymcc.service.ICourseTypeService;
import cn.qj.ymcc.vo.CourseTypeCrumbVo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale
 * @since 2025-07-24
 */
@Service
@Slf4j
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public List<CourseType> treeData() {
        //从redis获取数据 1.可以获取到 2.获取不到
        Object o = redisTemplate.opsForValue().get(BusinessConstants.REDIS_COURSE_TYPE_TREE_DATA);
        if(o != null){
            log.info("从redis中获取到课程分类数据:{}",o);
            return (List<CourseType>) o;
        }

        // 查询所有数据在数据库中 redis缓存
        List<CourseType> firstCourseTypes = getCourseTypes();
        log.info("从数据库中获取到课程分类数据:{}",firstCourseTypes);
        // 存入到redis中
        redisTemplate.opsForValue().set(BusinessConstants.REDIS_COURSE_TYPE_TREE_DATA,firstCourseTypes);
        return firstCourseTypes;
    }

    /**
     * 面包屑的实现
     * */
    @Override
    public List<CourseTypeCrumbVo> crumbs(Long courseTypeId) {
        // 判断参数
        if(courseTypeId==null){
            throw new GlobleBusinessException("参数异常");

        }

        // 根据id查询
        CourseType courseType = selectById(courseTypeId);

        if(courseType==null){
            throw new GlobleBusinessException("参数异常");
        }

        // 获取path，
        String[] idStrs = courseType.getPath().split("\\.");

        List<CourseType> courseTypes = selectBatchIds(Arrays.asList(idStrs));

        List<CourseTypeCrumbVo> courseTypeCrumbsVos = new ArrayList<>();

        courseTypes.forEach(type -> {
            EntityWrapper<CourseType> wrapper = new EntityWrapper<>();

            wrapper.eq("pid",type.getPid());
            wrapper.notIn("id",type.getId());
            List<CourseType> others = selectList(wrapper);

            courseTypeCrumbsVos.add(new CourseTypeCrumbVo(type,others));
        });

        return courseTypeCrumbsVos;
    }


    /**
     * 查询并构建课程分类树形结构
     * @return 树形结构的课程分类列表
     */
    private List<CourseType> getCourseTypes() {
        // 查询所有数据
        List<CourseType> allCourseTypes = selectList(null);

        // 将所有数据转换为树结构
        Map<Long, CourseType> courseTypeMap = new HashMap<>();
        for (CourseType courseType : allCourseTypes) {
            courseTypeMap.put(courseType.getId(), courseType);
        }

        // 第一层课程分类
        List<CourseType> firstLevelCourseTypes = new ArrayList<>();
        for (CourseType courseType : allCourseTypes) {
            if (courseType.getPid() == null || courseType.getPid() == 0) {
                firstLevelCourseTypes.add(courseType);
            } else {
                CourseType parent = courseTypeMap.get(courseType.getPid());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(courseType);
                }
            }
        }

        return firstLevelCourseTypes;
    }


    /**
     * 除了查询每一次都要删除redis数据
     * */
    @Override
    public boolean insert(CourseType entity) {
        redisTemplate.delete(BusinessConstants.REDIS_COURSE_TYPE_TREE_DATA);
        return super.insert(entity);
    }

    @Override
    public boolean deleteById(Serializable id) {
        redisTemplate.delete(BusinessConstants.REDIS_COURSE_TYPE_TREE_DATA);
        return super.deleteById(id);
    }

    @Override
    public boolean updateById(CourseType entity) {
        redisTemplate.delete(BusinessConstants.REDIS_COURSE_TYPE_TREE_DATA);
        return super.updateById(entity);
    }
}